home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <go32.h>
- #include <dpmi.h>
- #include <sys/farptr.h>
-
- #include "aspi.h"
- #include "aspi_int.h"
- #include "scsidefs.h"
-
- static int TB;
- static int DB;
- #define DOSS _go32_info_block.selector_for_linear_memory
- #define INT r.x.sp = r.x.ss = r.x.flags = 0, _go32_dpmi_simulate_int
- #define __dpmi_regs _go32_dpmi_registers
- #define GTB (_go32_info_block.linear_address_of_transfer_buffer & 0xfffff)
-
- union {
- SRB_HAInquiry hai;
- SRB_GDEVBlock gdb;
- SRB_ExecSCSICmd srb;
- SRB_Abort ab;
- SRB_BusDeviceReset res;
- } SRB_Everything;
-
- static aspi_fd = -1;
- static int aspi_entry_seg;
- static int aspi_entry_ofs;
- static _go32_dpmi_seginfo dos_buf;
-
- long aspi_buffer_length = 128 * 1024;
- char aspi_sense[SENSE_LEN];
-
- static void
- aspi_entry(void *srb, int srblen)
- {
- __dpmi_regs r;
- int i;
- int sp = GTB + 4090;
- /* printf("%x = %x + 4090\n", sp, GTB);*/
- dosmemput(srb, srblen, TB);
- /* printf("go32's TB at 0x%x 0x%x\n", _go32_info_block.linear_address_of_transfer_buffer, GTB); */
- /* printf("entry: SRB at 0x%lx (dos TB at 0x%x)\n", srb, TB); */
- memset(&r, 0, sizeof(r));
- r.x.cs = aspi_entry_seg;
- r.x.ip = aspi_entry_ofs;
- sp -= 2; _farpokew(DOSS, sp, TB >> 4);
- sp -= 2; _farpokew(DOSS, sp, TB & 15);
- r.x.ss = GTB >> 4;
- r.x.sp = (sp - r.x.ss*16);
- /* printf("entry: go %04x:%04x, stack %04x:%04x (now 0x%x)\n",
- r.x.cs, r.x.ip, r.x.ss, r.x.sp, sp); */
- #if 0
- printf("stack[0x%x]: ", r.x.ss * 16 + r.x.sp);
- for (i=0; i<37; i++)
- printf(" %02x", _farpeekb(DOSS, r.x.ss * 16 + r.x.sp + i));
- printf("\n");
- #endif
- _go32_dpmi_simulate_fcall(&r);
- while (_farpeekb(DOSS, TB+1) == 0);
- dosmemget(TB, srblen, srb);
- }
-
- int
- aspi_init(void)
- {
- __dpmi_regs r;
- SRB_HAInquiry hai;
-
- setbuf(stdout, 0);
- dos_buf.size = (aspi_buffer_length/16) + (sizeof(SRB_Everything)+15) / 16;
- if (_go32_dpmi_allocate_dos_memory(&dos_buf))
- {
- fprintf(stderr, "ASPI Error: Not able to allocate %d Kb buffer\n", aspi_buffer_length / 1024);
- aspi_fd = -1;
- return -1;
- }
- TB = dos_buf.rm_segment * 16;
- DB = TB + (sizeof(SRB_Everything) + 15) & ~15;
-
- aspi_fd = open("SCSIMGR$", O_RDONLY);
- if (aspi_fd < 0)
- {
- perror("SCSIMGR$");
- aspi_fd = -1;
- return -1;
- }
-
- r.x.ax = 0x4402;
- r.x.bx = aspi_fd;
- r.x.cx = 4;
- r.x.ds = TB >> 4;
- r.x.dx = TB & 15;
- INT(0x21, &r);
- aspi_entry_ofs = _farpeekw(DOSS, TB);
- aspi_entry_seg = _farpeekw(DOSS, TB+2);
- close(aspi_fd);
- aspi_fd = 0;
-
- memset(&hai, 0, sizeof(hai));
- hai.SRB_Cmd = SC_HA_INQUIRY;
- aspi_entry(&hai, sizeof(hai));
-
- return hai.HA_Count;
- }
-
- int
- aspi_close(void)
- {
- if (aspi_fd)
- return;
- _go32_dpmi_free_dos_memory(&dos_buf);
- aspi_fd = -1;
- return 0;
- }
-
- int
- aspi_device_type(int aspi_id)
- {
- SRB_GDEVBlock gd;
- if (aspi_fd)
- return;
- memset(&gd, 0, sizeof(gd));
- gd.SRB_Cmd = SC_GET_DEV_TYPE;
- gd.SRB_HaId = ASPI_ID2HOSTAD(aspi_id);
- gd.SRB_Target = ASPI_ID2TARGET(aspi_id);
- gd.SRB_Lun = ASPI_ID2LUN(aspi_id);
- aspi_entry(&gd, sizeof(gd));
- return (gd.SRB_Status == SS_COMP) ? gd.SRB_DeviceType : -1;
- }
-
- int
- aspi_exec(int id, void *buf, int buflen, int rw, char *cdb, int cdblen)
- {
- char *cptr;
- SRB_ExecSCSICmd srb;
-
- if (aspi_fd)
- return;
-
- memset(&srb, 0, sizeof(srb));
- srb.SRB_Cmd = SC_EXEC_SCSI_CMD;
- srb.SRB_Status = 0;
- srb.SRB_HaId = ASPI_ID2HOSTAD(id);
- srb.SRB_Flags = SRB_DIR_SCSI;
- srb.SRB_Target = ASPI_ID2TARGET(id);
- srb.SRB_Lun = ASPI_ID2LUN(id);
- srb.SRB_BufLen = buflen;
- srb.SRB_SenseLen = SENSE_LEN;
- srb.SRB_BufPointerOfs = DB & 15;
- srb.SRB_BufPointerSeg = DB >> 4;
- srb.SRB_CDBLen = cdblen;
- memcpy(srb.cptr, cdb, cdblen);
- if (rw & ASPI_RW_WRITE)
- dosmemput(buf, buflen, DB);
- aspi_entry(&srb, sizeof(srb));
- if (rw & ASPI_RW_READ)
- dosmemget(DB, buflen, buf);
- memcpy(aspi_sense, srb.cptr+cdblen, SENSE_LEN);
- return srb.SRB_Status;
- }
-